﻿using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace FluentTagsGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            string file = @"content\xhtml1-strict.xsd";

            var elements = new TagElements(file);

            string template = File.OpenText(@"content\template.txt").ReadToEnd();

            string outputPath = ConfigurationManager.AppSettings["outputDir"];

            foreach (TagElement e in elements)
            {
                var classContent = GenerateClass(e, elements, template);

                string className = CSharpNaming.ClassifyName(e.Name);
                string path = Path.Combine(outputPath, className + "Tag.cs");
                using (StreamWriter sw = new StreamWriter(path, false))
                {
                    sw.Write(classContent);
                }
            }
        }

        private static string GenerateClass(TagElement e, TagElements elements, string template)
        {
            DebugWriteElementInfo(e);

            string className = CSharpNaming.ClassifyName(e.Name);

            var classContent = new StringBuilder(template);

            classContent.Replace("${Name}", className).Replace("${TagName}", e.Name);

            DebugWriteAttributes(e);

            var attributeMethodGenerator = new AttributeMethodGenerator(className, classContent, e.Attributes);
            classContent = attributeMethodGenerator.Generate();

            var childElements = e.AllChildElements(elements);

            DebugWriteElements(childElements);

            var ctorGenerator = new CtorGenerator(className, classContent, e.IsText);
            classContent = ctorGenerator.Generate();

            var methodGenerator = new MethodGenerator(className, classContent, childElements);
            classContent = methodGenerator.Generate();

            var textMethodGenerator = new TextMethodGenerator(className, classContent, e.IsText);
            classContent = textMethodGenerator.Generate();

            return classContent.ToString();

        }

        private static void DebugWriteElementInfo(TagElement e)
        {
            Debug.WriteLine("");
            Debug.WriteLine(e.Name);
            Debug.WriteLine("  Comment: " + e.Comment);
        }

        private static void DebugWriteElements(List<TagElement> childElements)
        {
            Debug.Write("  Elements[");
            var spaceSeperatedElementNames = string.Join(" ", childElements.Select(ele => ele.Name));
            Debug.Write(spaceSeperatedElementNames);
            Debug.WriteLine("]");
        }

        private static void DebugWriteAttributes(TagElement e)
        {
            Debug.Write("  Attributes[");
            foreach (Attribute a in e.Attributes)
            {
                Debug.Write(" " + a.Name + ":" + a.ClrType);
            }
            Debug.WriteLine("]");
        }

    }
}
